from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from django.test import LiveServerTestCase
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
import unittest
import time,sys
from unittest import skip
import os
from datetime import datetime
from selenium.common.exceptions import WebDriverException
DEFAULT_WAIT = 5
SCREEN_DUMP_LOCATION = os.path.abspath(
os.path.join(os.path.dirname(__file__), 'screendumps')
)

class FunctionalTest(StaticLiveServerTestCase):

	@classmethod
	def setUpClass(cls): # ➊
		for arg in sys.argv: # ➋
			if 'liveserver' in arg: # ➌
				cls.server_url = 'http://' + arg.split('=')[1] # ➍
				return # ➎
		super().setUpClass()
		cls.server_url = cls.live_server_url

	@classmethod
	def tearDownClass(cls):
		if cls.server_url == cls.live_server_url:
			super().tearDownClass()

	def setUp(self): # ➋
		self.browser = webdriver.Firefox()
		self.browser.implicitly_wait(DEFAULT_WAIT)

	def tearDown(self): # ➌
		if self._test_has_failed():
			if not os.path.exists(SCREEN_DUMP_LOCATION):
				os.makedirs(SCREEN_DUMP_LOCATION)
			for ix, handle in enumerate(self.browser.window_handles):
				self._windowid = ix
				self.browser.switch_to_window(handle)
				self.take_screenshot()
				self.dump_html()
		self.browser.quit()
		super().tearDown()

	def wait_for(self,function_with_assertion,timeout = DEFAULT_WAIT):
		start_time = time.time()
		while time.time() - start_time < timeout:
			try:
				return function_with_assertion()
			except (AssertionError,WebDriverException):
				time.sleep(0.1)
			return function_with_assertion()

	def _test_has_failed(self):
		for method,error in self._outcome.errors:
			if error:
				return True
		return False

	def take_screenshot(self):
		filename = self._get_filename() + '.png'
		print('screenshotting to ',filename)
		self.browser.get_screenshot_as_file(filename)

	def dump_html(self):
		filename = self._get_filename() +'.html'
		print('dumping page HTML to',filename)
		with open(filename,'w') as f:
			f.write(self.browser.page_source)

	def _get_filename(self):
		timestamp = datetime.now().isoformat().replace(':', '.')[:19]
		return '{folder}/{classname}.{method}-window{windowid}-{timestamp}'.format(
			folder=SCREEN_DUMP_LOCATION,
			classname=self.__class__.__name__,
			method=self._testMethodName,
			windowid=self._windowid,
			timestamp=timestamp
		) 

	def check_for_row_in_list_table(self,row_text):
		table = self.browser.find_element_by_id('id_list_table')
		rows = table.find_elements_by_tag_name('tr')
		self.assertIn(row_text,[row.text for row in rows])

	def get_item_input_box(self):
		return self.browser.find_element_by_id('id_text')

